<template>
  <div>
    <el-form >
      <el-form-item label="SPU名称">
        <el-input placeholder="请输入SPU名称" v-model="spuParams.spuName"></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌">
        <el-select placeholder="请选择" v-model="spuParams.tmId">
          <el-option v-for="(trademark,index) in allTradeMarkArr" :key="trademark.id"  :label="trademark.tmName" :value="trademark.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input placeholder="请输入SPU描述" type="textarea" v-model="spuParams.description" ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
        <el-upload
          v-model:file-list="imgListArr"
          action="/api/admin/product/fileUpload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleSuccess"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 400px; height: 400px; margin: 0 auto; display: block" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <el-select v-model="unSaleAttrIdAndName" :placeholder="unSelectSaleAttr.length>0?`您还有${unSelectSaleAttr.length}未选择`:`没得选啦`" >
          <el-option :label="sale.name" :value="`${sale.id}:${sale.name}`" v-for="(sale,index) in unSelectSaleAttr" :key="sale.id"></el-option>
        </el-select>
        <el-button style="margin-left:10px" type="primary" size="default" :icon="Plus" :disabled="!unSaleAttrIdAndName" @click="addSaleAttr">添加销售属性</el-button>
        <el-table :data="spuHasSaleAttrArr"  border stripe style="margin: 10px 0" >
            <el-table-column label="序号" type="index" align="center" width="80px" ></el-table-column>
            <el-table-column label="属性名" width="150px" prop="saleAttrName"  ></el-table-column>
            <el-table-column label="属性值名称列表">
                 <!-- 底下的row:销售属性对象 -->
              <template #="{row,$index}">
                 <!-- 利用el-tag展示销售属性值 -->
                <el-tag 
                type="success" 
                style="margin:0px 5px" 
                closable 
                v-for="(saleValue,index) in row.spuSaleAttrValueList"  
                :key="saleValue.id"
                @close="row.spuSaleAttrValueList.splice(index,1)"
                >{{saleValue.saleAttrValueName}}</el-tag>
                <el-input v-model="row.inputValue" @blur="toLook(row)" style="width:100px ;" v-if="row.flag" placeholder="请你输入属性值" size="small" ></el-input>
                <el-button v-else type="primary" size="small" @click="toEdit(row)" :icon="Plus" ></el-button>
                
                
              </template>
            </el-table-column>
            <el-table-column label="操作" width="150px">
                <template #="{row,$index}">
                  <el-button type="danger" size="small" :icon="Delete" @click="spuHasSaleAttrArr.splice($index,1)"></el-button>
                </template>
              
            </el-table-column>
        </el-table>
         <el-button type="primary" size="default" @click="save" >保存</el-button>
                                                             <!-- 点击取消按钮,触发自定义事件changeScene,并传参0 -->
         <el-button style="margin-left: 10px;" size="default" @click="cancel" >取消</el-button> 
    </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
// 引入组合式API
import { ref,computed } from "vue";
import { Plus,Delete } from "@element-plus/icons-vue";
// 引入组件
import { ElMessage } from "element-plus";
// 引入数据类型
import type { UploadProps, UploadUserFile } from "element-plus";
//引入请求函数
import {reqAllaTradeMark,reqAllSaleAttr,reqImgList,reqSpuHasSaleAttr,reqAddOrUpdateSpu} from '../../../api/product/spu/spu'
// 定义变量,将来存储添加或修改需要带给服务器的参数
let spuParams = ref({})
//已有SPU下的全部品牌数据
let allTradeMarkArr = ref([]);
//获取已有SPU下照片墙的数据
let imgListArr = ref([]);
//获取已有SPU，拥有销售属性
let spuHasSaleAttrArr = ref([]);
//获取全部销售属性[不管任何SPU销售属性最多三个]
let allSaleAttrArr = ref([]);

// 定义收集SPU还未选择销售属性ID与名字的变量
// 初始为空,v-model绑定
let unSaleAttrIdAndName = ref('')


// 图片墙相关数据
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

// 移除图片
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
};

// 预览图片
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

//图片上传成功的回调
const handleSuccess = (response, uploadFile, uploadFiles) => {
  //前两个参数:图片上传成功的信息
  //最后的参数:图片上传成功以后，照片墙全部图片数据
  imgListArr.value = uploadFiles;
};

//提供一个方法:将来父组件可以借用的方法----获取sku下的全部数据
// row 点击修改按钮时传的参数,代表的是当前这一条的所有数据
const initHasSpuData = async (row)=>{
     // 存储数据--添加或修改需要带给服务器的参数
     spuParams.value = row
    // 获取已有SUP下的全部品牌数据
    let sp1 = reqAllaTradeMark()
    //获取全部销售属性[不管任何SPU销售属性最多三个]
    let sp2 = reqAllSaleAttr()
    //获取已有SPU下照片墙的数据
    let sp3 = reqImgList(row.id)
    //获取当前SPU已有销售属性
    let sp4 = reqSpuHasSaleAttr(row.id)
    // 获取全部服务器返回的数据
    let result = await Promise.all([sp1,sp2,sp3,sp4])
    // 存储全部品牌数据
    allTradeMarkArr.value = result[0]
    // 由于服务器返回的数据格式并非人家照片墙需要的(key不同),所以需要对数据进行处理
    imgListArr.value = result[2].map((item)=>{
      return {
        name:item.imgName,
        url:item.imgUrl
      }

    })
    
    // 存储全部销售属性
    allSaleAttrArr .value = result[1]
    // 存储已有SPU下照片墙的数据
    // imgListArr.value = result[2]
    // 存储当前SPU已有销售属性
    spuHasSaleAttrArr.value = result[3]
}

// 计算当前spu,含没有选择的销售属性
let unSelectSaleAttr = computed(()=>{
         //外层数组:三个元素  版本、尺码、颜色  -->需要把版本、尺码过滤出来
    let result =  allSaleAttrArr.value.filter(item=>{
              //filter回调函数需要返回布尔值:真、代表过滤出来 false：代表新的数组不要
              //数组里面目前:颜色
              return  spuHasSaleAttrArr.value.every((item1)=>{
                       
                       return  item.name != item1.saleAttrName;
              })
    })

    return  result;
})

// 点击销售属性值按钮的回调
const addSaleAttr=()=>{
  // 新增的销售属性ID与名字
  const [baseSaleAttrId,saleAttrName] = unSaleAttrIdAndName.value.split(':')
  // 服务器需要销售属性对象
  let newSaleAttr = {baseSaleAttrId,saleAttrName,spuSaleAttrValueList:[]}
  // 向SPU已有的数组里面追加新增销售属性
  spuHasSaleAttrArr.value.push(newSaleAttr)
  // 清空下拉的数据
  unSaleAttrIdAndName.value= ''
}

// 点击加号按钮变为编辑模式回调
const toEdit = (row)=>{
  // 动态追加flag属性
  // Proxy对象:动态追的属性也是响应式的
   row.flag = true
  //  追加一个属性: 收集销售属性值--有一个起始数值
  row.inputValue= ''
}

// input失去焦点的回调
const toLook = (row)=>{
  // 如果收集属性值为空(inputValue动态添加新的属性)
  if(row.inputValue.trim()==''){
    // 提示信息
    ElMessage({
      type:'error',
      message:'不能为空'
    })
     // 然后显示成按钮模式
     row.flag = false
    return
  }

  // 收集属性值不能跟前面的重复(找出重复的属性值)
  let repeat = row.spuSaleAttrValueList.find((item)=>{
    // item:已有的销售属性值对象        row.inputValue: 新增属性值名称
    return item. saleAttrValueName == row.inputValue
  })

  // 如果重复,后面程序无法执行
  if(repeat){
    // 信息提示
    ElMessage({
      type:'error',
      message:'属性值不能重复'
    });
    // 清空最新的属性值
    row.inputValue = ''
    // 然后显示成按钮模式
    row.flag = false
    return
  }
// 显示button设置
  row.flag=false
  // 如果都是合法属性值,新增属性值
  let newSaleattrVal={
    baseSaleAttrId :row.baseSaleAttrId,  
    saleAttrValueName:row.inputValue
  }
  // 追加到当前销售属性值的数组中
  row.spuSaleAttrValueList.push(newSaleattrVal)
  // 清空收集到的属性值数据
  row.inputValue = ''
}

// 保存按钮的事件回调
const save =async ()=>{
  // 整理参数--照片墙数据
  spuParams.value.spuImageList = imgListArr.value.map((item)=>{
          return {
            imgName:item.name,
            imgUrl:(item.response&&item.response.data)||item.url
          }
  })
  //整理销售属性数据
  spuParams.value.spuSaleAttrList =spuHasSaleAttrArr.value

  // 发请求
  try {
    await reqAddOrUpdateSpu(spuParams.value)
    ElMessage({
       type:'success',
       message:spuParams.value.id?'修改成功':'添加成功'
    })
    // 调用自定以事件,传参,切换场景,并区分修改还是更新
    emit('changeScene',{
      scenes:0,
      flag:spuParams.value.id?'updat':'add'
   })
      //  调用清除数据的方法
      resetData()
  } catch (error) {
    ElMessage({
       type:'error',
       message:spuParams.value.id?'修改失败':'添加失败'
    })
  }
 
}

// 取消按钮的事件回调
const cancel = ()=>{
   emit('changeScene',{
      scenes:0,
      flag:spuParams.value.id?'updat':'add'
   })
  //  调用清除数据的方法
   resetData()
}

// 清空数据
const resetData = ()=>{
  spuParams.value ={}
  imgListArr.value= []
  spuHasSaleAttrArr.value=[]
}

// 供父组件调用的  两个请求,获取品牌数据,获取销售属性
const initAddSpu = async (C3Id:number|string)=>{
  // 追加SPU三级分类的id
  spuParams.value.category3Id = C3Id
  // 获取已有SUP下的全部品牌数据
  let sp1 = reqAllaTradeMark()
  //获取全部销售属性[不管任何SPU销售属性最多三个]
  let sp2 = reqAllSaleAttr()
  let result = await Promise.all([sp1,sp2])
     // 存储全部品牌数据
     allTradeMarkArr.value = result[0]
     // 存储全部销售属性
     allSaleAttrArr .value = result[1]

}

// 子组件触发父组件中的自定义事件
let emit = defineEmits(['changeScene'])
// 对外暴露方法,方便父组件引用
defineExpose({
    initHasSpuData,
    initAddSpu

    })
</script>

<style scoped></style>
